package main

import (
	"errors"
	"fmt"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"github.com/xuri/excelize/v2"
	"io"
	"net/http"
	"os"
	"path"
	"regexp"
	"strings"
	"time"
)

var excelRows [][]string
var willExecCmd []string
var execCode string
var commandText *widget.Entry
var reqProcess string
var reqWdt *widget.Label
var reqProcessContainer *fyne.Container

func autoWay(w fyne.Window) *fyne.Container {
	//a := app.New()
	// 创建一个新窗口
	//w := a.NewWindow("文件内容读取")
	infoTxt := widget.NewLabel("格式为excel类型，请点击下载模板")
	// 创建一个文本区域用于显示文件内容
	contentText := widget.NewMultiLineEntry()
	// 设置自动换行
	contentText.Wrapping = fyne.TextWrapWord
	//contentText.SetReadOnly(true)

	infoCommandTxt := widget.NewLabel("命令预览")
	copyBtn := widget.NewButtonWithIcon("复制", theme.ContentCopyIcon(), func() {
		//获取contentText中的内容
		text := commandText.Text
		if text == "" {
			dialog.ShowError(
				// 弹出错误提示框
				&os.PathError{Op: "复制操作", Path: "文本内容", Err: os.ErrNotExist},
				w,
			)
			return
		}
		dialog.ShowInformation("复制成功", text, w)
		w.Clipboard().SetContent(text)
	})
	copyBtn.Importance = widget.HighImportance
	copyBtn.Refresh()
	validBtn := widget.NewButtonWithIcon("验证", theme.ConfirmIcon(), func() {
		for i, row := range excelRows {
			if i == 0 {
				continue
			}
			if checkFileType(row[1]) == errorType {
				continue
			}
			reqProcess = ""
			go validateRequest(row[1])
		}
	})
	previewContainer := container.New(layout.NewHBoxLayout(), infoCommandTxt, copyBtn, validBtn)
	commandText = widget.NewMultiLineEntry()
	commandText.Wrapping = fyne.TextWrapWord

	// 创建一个按钮用于触发文件选择对话框
	uploadButton := widget.NewButtonWithIcon("选择文件", theme.UploadIcon(), func() {
		// 显示文件打开对话框
		dialog.ShowFileOpen(func(reader fyne.URIReadCloser, err error) {
			if err != nil {
				// 处理错误
				dialog.ShowError(err, w)
				return
			}
			if reader == nil {
				// 用户取消选择
				return
			}
			defer reader.Close()
			//使用excelize读取excel文件
			// 获取文件路径
			filePath := reader.URI().Path()
			// 使用 excelize 读取 excel 文件
			f, err := excelize.OpenFile(filePath)
			if err != nil {
				dialog.ShowError(err, w)
				return
			}
			defer f.Close()

			// 获取第一个工作表的名称
			sheetName := f.GetSheetName(0)
			// 获取工作表中的所有行
			rows, err := f.GetRows(sheetName)
			excelRows = rows
			if err != nil {
				dialog.ShowError(err, w)
				return
			}

			var content string
			for _, row := range rows {
				for _, colCell := range row {
					content += colCell + "\t"
				}
				content += "\n"
			}
			contentText.SetText(content)
		}, w)
	})
	uploadButton.Importance = widget.WarningImportance
	uploadButton.Refresh()

	query := NewQuery()
	htmlStr, docStr := query.GetConfig()
	genButton := widget.NewButtonWithIcon("生成命令", theme.DocumentSaveIcon(), func() {
		prefix := "rm -rf" + "  "
		for i, row := range excelRows {
			if i == 0 {
				continue
			}
			typeOf := checkFileType(row[1])
			switch typeOf {
			case errorType:
				dialog.ShowError(errors.New("无效"), w)
			case docType:
				text := strings.NewReplacer("\r\n", "", "\r", "", "\n", "").Replace(row[1])
				regex := `^(http|https)://(www\.)?([a-zA-Z0-9.-]+(?:\.[a-zA-Z]{2,})+)(/.*)?$`
				re := regexp.MustCompile(regex)
				matches := re.FindStringSubmatch(text)
				if matches != nil && len(matches) >= 5 {
					newPath := fmt.Sprintf("%s", matches[4])
					willExecCmd = append(willExecCmd, htmlStr+newPath)
				}
			case htmlType:
				willExecCmd = append(willExecCmd, docStr+"/"+removeProtocol(row[1]))
			}
		}
		//最后讲prefix 与      willExecCmd进行连接
		tmpStr := ""
		for _, s := range willExecCmd {
			tmpStr += s + " "
		}
		execCode = prefix + tmpStr
		commandText.SetText(execCode)
	})

	genButton.Importance = widget.SuccessImportance
	genButton.Refresh()

	clearButton := widget.NewButtonWithIcon("清空", theme.ContentClearIcon(), func() {
		excelRows = [][]string{}
		willExecCmd = []string{}
		contentText.SetText("")
		execCode = ""
		commandText.SetText("")
		reqWdt.SetText("状态预览：")
		reqProcessContainer.Refresh()
	})
	clearButton.Importance = widget.DangerImportance
	clearButton.Refresh()

	// 模板按钮
	templateButton := widget.NewButtonWithIcon("模板", theme.FolderNewIcon(), func() {
		// 假设模板文件名为 template.xlsx，且在当前目录下
		templateFilePath := "template.xlsx"
		// 检查模板文件是否存在
		if _, err := os.Stat(templateFilePath); os.IsNotExist(err) {
			dialog.ShowError(err, w)
			return
		}
		// 打开模板文件
		templateFile, err := os.Open(templateFilePath)
		if err != nil {
			dialog.ShowError(err, w)
			return
		}
		// 生成当前时间戳作为默认文件名
		timestamp := time.Now().Unix()
		defaultFileName := fmt.Sprintf("%d.xlsx", timestamp)
		// 显示文件保存对话框
		saveDialog := dialog.NewFileSave(func(writer fyne.URIWriteCloser, err error) {
			if err != nil {
				dialog.ShowError(err, w)
				// 关闭模板文件
				templateFile.Close()
				return
			}
			if writer == nil {
				// 用户取消保存
				// 关闭模板文件
				templateFile.Close()
				return
			}
			defer writer.Close()

			// 将模板文件内容复制到用户选择的保存位置
			_, err = io.Copy(writer, templateFile)
			if err != nil {
				dialog.ShowError(err, w)
			} else {
				dialog.ShowInformation("下载成功", "模板文件下载成功", w)
			}
			// 确保在文件复制完成后关闭模板文件
			templateFile.Close()
		}, w)
		// 设置默认文件名
		saveDialog.SetFileName(defaultFileName)
		// 显示对话框
		saveDialog.Show()
	})
	templateButton.Importance = widget.LowImportance
	templateButton.Refresh()
	// 创建一个垂直布局容器，包含选择按钮和文本区域
	buttonContainer := container.New(layout.NewHBoxLayout(), uploadButton, genButton, clearButton, templateButton)

	reqWdt = widget.NewLabel("状态：" + reqProcess)
	reqProcessContainer = container.New(layout.NewHBoxLayout(), reqWdt)
	content := container.NewVBox(infoTxt, buttonContainer, contentText, previewContainer, commandText, reqProcessContainer)
	return content
}

// 检查字符串文件路径https://www.quxian.gov.cn/uploadfile/1/Attachment/1c812ec11ac.xlsx中的文件类型
const (
	errorType = iota
	htmlType
	docType
)

func checkFileType(fileName string) int {
	//todo 根据后缀判断，例如https://www.quxian.gov.cn/uploadfile/1/Attachment/1c812ec10ac.xlsx得到.xlsx,
	// https://www.quxian.gov.cn/xxgk-show-23674.html得到.html
	// 查找最后一个 . 的位置
	// 从 URL 中提取文件名
	baseName := path.Base(fileName)
	// 查找最后一个 . 的位置
	lastDotIndex := strings.LastIndex(baseName, ".")
	if lastDotIndex == -1 {
		// 如果没有找到 .，说明没有文件后缀，返回空字符串
		return errorType
	} else {
		fileType := baseName[lastDotIndex:]
		if fileType == ".html" {
			return htmlType
		} else {
			return docType
		}
	}
}

// 发送一个网络请求，当返回404时，返回true，否则返回false
func validateRequest(url string) {
	client := &http.Client{}
	req, _ := http.NewRequest("GET", url, nil)

	resp, _ := client.Do(req)
	defer resp.Body.Close()

	if resp.StatusCode == 404 {
		//保存历史记录
		if url != "" {
			history := History{
				RmDoc:     url,
				CreatedAt: time.Now(),
			}
			Gorm.Create(&history)
		}
		reqProcess += "✅" + url + ":" + fmt.Sprintf("已删除：%d\n", resp.StatusCode)
	} else {
		reqProcess += "❌" + url + ":" + fmt.Sprintf("未删除：%d\n", resp.StatusCode)
	}
	reqWdt.SetText(reqProcess)
	reqProcessContainer.Refresh()
}
